﻿namespace Trading.Studio

open System
open System.Windows
open System.Reactive.Linq 

type IView<'M, 'E> = 
    abstract Model : 'M with set
    abstract Events : IObservable<'E> 

[<AbstractClass>]
type ViewBase<'M, 'E>(windowResource, ?assemblyName) =
    
    let assemblyName = defaultArg assemblyName ""
    let resourseUri = sprintf "/%s;component/%s.xaml" assemblyName windowResource
    let wpfWindow = Application.LoadComponent(resourceLocator = Uri(resourseUri, UriKind.Relative)) :?> Window

    member this.UnderlyingWpfWindow = wpfWindow
     
    static member (?) (view : ViewBase<'M, 'E>, name : string) = 
      match view.UnderlyingWpfWindow.FindName(name) with
      | null -> invalidArg "Name" ("Cannot find control with name: " + name)
      | x -> x |> unbox

    abstract EventStreams : IObservable<'E> array
    abstract SetBindings : unit -> unit
    default this.SetBindings() = ()

    interface IView<'M, 'E> with
        member this.Model 
            with set (x : 'M) = 
                this.UnderlyingWpfWindow.DataContext <- x; 
                this.SetBindings()
        member this.Events = this.EventStreams |> Observable.Merge



